/*
* ========== Copyright Header Begin ==========================================
* 
* OpenSPARC T1 Processor File: v9_inst_asm_v9.s
* Copyright (c) 2006 Sun Microsystems, Inc.  All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
* 
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
* 
* The above named program is distributed in the hope that it will be 
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* General Public License for more details.
* 
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
* 
* ========== Copyright Header End ============================================
*/
#pragma ident "@(#)1.3	01/10/09	v9_inst_asm_v9.s"
	
#include <sys/asm_linkage.h>
! Copyright (C) 1991, Sun Microsystems, Inc.
!
! This file contains SPARC assembly language for Sparc V9 instructions
!

#define SETX(value,rd,rtmp1,rtmp2)				\
	or	%g0,%o7,rtmp1	;				\
1:	call	.+8		;				\
	sethi	%hi(_GLOBAL_OFFSET_TABLE_-(1b-.)),rtmp2 ;	\
	add	rtmp2,%lo(_GLOBAL_OFFSET_TABLE_-(1b-.)),rtmp2 ;	\
	add	rtmp2,%o7,rtmp2	;				\
	or	%g0,rtmp1,%o7	;				\
	ldx	[rtmp2+%lo(value)],rd ;
	
	ENTRY(iflush)
	retl
	flush	%o0
	SET_SIZE(iflush)

	ENTRY(addcc_instr)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
 	addcc	%o0, %o1, %o1
	rd	%ccr, %o5
	stx	%o1, [%o2]
        retl
	stb	%o5, [%o3]
	SET_SIZE(addcc_instr)

	ENTRY(addx_instr)
 	wr	%o2, %ccr
	retl
 	addc	%o0, %o1, %o0
	SET_SIZE(addx_instr)

	ENTRY(addxcc_instr)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
	ldub	[%o3], %o5
	wr	%o5, %ccr
 	addccc	%o0, %o1, %o1
	rd	%ccr, %o5
	stx	%o1, [%o2]
	retl
	stb	%o5, [%o3]
	SET_SIZE(addxcc_instr)

	ENTRY(taddcc_instr)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
	or	%o0, %o1, %o5 ! check if bit 1 or 0 of either   
	and	%o5, 3, %o5 ! operand is nonzero
	movrnz	%o5, 2, %o5
 	addcc	%o0, %o1, %o1
	rd	%ccr, %o4
	or	%o4, %o5, %o4
	stx	%o1, [%o2]
        retl
	stb	%o4, [%o3]
	SET_SIZE(taddcc_instr)

	ENTRY(subcc_instr_rd0)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
 	subcc	%o0, %o1, %g0
	rd	%ccr, %o5
        retl
	stb	%o5, [%o2]
	SET_SIZE(subcc_instr_rd0)

	ENTRY(subcc_instr_simm)
	ldx	[%o0], %o0
 	subcc	%o0, %o1, %o1
	rd	%ccr, %o5
	stx	%o1, [%o2]
        retl
	stb	%o5, [%o3]
	SET_SIZE(subcc_instr_simm)

	ENTRY(subcc_instr_simm_rd0)
	ldx	[%o0], %o0
 	subcc	%o0, %o1, %g0
	rd	%ccr, %o5
        retl
	stb	%o5, [%o2]
	SET_SIZE(subcc_instr_simm_rd0)

	ENTRY(subcc_instr)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
 	subcc	%o0, %o1, %o1
	rd	%ccr, %o5
	stx	%o1, [%o2]
        retl
	stb	%o5, [%o3]
	SET_SIZE(subcc_instr)

	ENTRY(umul_asm)
 	umul  	%o0, %o1, %o1
	rd	%y, %o5
	stx	%o1, [%o2]
        retl
	st	%o5, [%o3]
	SET_SIZE(umul_asm)

	ENTRY(udiv_asm)
	wr	%o3, %y
 	udiv  	%o0, %o1, %o1
        retl
	stx	%o1, [%o2]
	SET_SIZE(udiv_asm)

	ENTRY(smul_asm)
 	smul  	%o0, %o1, %o1
	rd	%y, %o5
	stx	%o1, [%o2]
        retl
	st	%o5, [%o3]
	SET_SIZE(smul_asm)

	ENTRY(mulscc_asm)
	ld	[%o4], %o5
	wr	%o5, %y
	ldub	[%o3], %o5
	wr	%o5, %ccr
 	mulscc	%o0, %o1, %o0
	rd	%ccr, %o5
	stb	%o5, [%o3]
	rd	%y, %o5
	stx	%o0, [%o2]
        retl
	st	%o5, [%o4]
	SET_SIZE(mulscc_asm)

	ENTRY(sdiv_asm)
	wr	%o3, %y
 	sdiv	%o0, %o1, %o1
        retl
	stx	%o1, [%o2]
	SET_SIZE(sdiv_asm)

	ENTRY(umulcc_asm)
 	umulcc	%o0, %o1, %o1
	rd	%ccr, %o5
	stb	%o5, [%o3]
	rd	%y, %o5
	stx	%o1, [%o2]
        retl
	st	%o5, [%o4]
	SET_SIZE(umulcc_asm)

	ENTRY(udivcc_asm)
	wr	%o4, %y
 	udivcc	%o0, %o1, %o1
	rd	%ccr, %o5
	stb	%o5, [%o3]
        retl
	stx	%o1, [%o2]
	SET_SIZE(udivcc_asm)

	ENTRY(smulcc_asm)
 	smulcc	%o0, %o1, %o1
	rd	%ccr, %o5
	stb	%o5, [%o3]
	rd	%y, %o5
	stx	%o1, [%o2]
        retl
	st	%o5, [%o4]
	SET_SIZE(smulcc_asm)

	ENTRY(sdivcc_asm)
	wr	%o4, %y
 	sdivcc	%o0, %o1, %o1
	rd	%ccr, %o5
	stb	%o5, [%o3]
        retl
	stx	%o1, [%o2]
	SET_SIZE(sdivcc_asm)

	ENTRY(subx_instr)
 	wr	%o2,%ccr
	retl
 	subc	%o0, %o1, %o0
	SET_SIZE(subx_instr)

	ENTRY(subxcc_instr)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
	ldub	[%o3], %o5
	wr	%o5, %ccr
 	subccc	%o0, %o1, %o1
	rd	%ccr, %o5
	stx	%o1, [%o2]
	retl
	stb	%o5, [%o3]
	SET_SIZE(subxcc_instr)

	ENTRY(tsubcc_instr)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
	or	%o0, %o1, %o5 ! check if bit 1 or 0 of either   
	and	%o5, 3, %o5 ! operand is nonzero
	movrnz	%o5, 2, %o5
 	subcc	%o0, %o1, %o1
	rd	%ccr, %o4
	or	%o4, %o5, %o4
	stx	%o1, [%o2]
        retl
	stb	%o4, [%o3]
	SET_SIZE(tsubcc_instr)

	ENTRY(andcc_instr)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
 	andcc	%o0, %o1, %o1
	rd	%ccr, %o5
	stx	%o1, [%o2]
        retl
	stb	%o5, [%o3]
	SET_SIZE(andcc_instr)

	ENTRY(andncc_instr)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
 	andncc	%o0, %o1, %o1
	rd	%ccr, %o5
	stx	%o1, [%o2]
        retl
	stb	%o5, [%o3]
	SET_SIZE(andncc_instr)

	ENTRY(orcc_instr)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
 	orcc	%o0, %o1, %o1
	rd	%ccr, %o5
	stx	%o1, [%o2]
        retl
	stb	%o5, [%o3]
	SET_SIZE(orcc_instr)

	ENTRY(orncc_instr)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
 	orncc	%o0, %o1, %o1
	rd	%ccr, %o5
	stx	%o1, [%o2]
        retl
	stb	%o5, [%o3]
	SET_SIZE(orncc_instr)

	ENTRY(xorcc_instr)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
 	xorcc	%o0, %o1, %o1
	rd	%ccr, %o5
	stx	%o1, [%o2]
        retl
	stb	%o5, [%o3]
	SET_SIZE(xorcc_instr)

	ENTRY(xnor_instr)
        retl
 	xnor	%o0, %o1, %o0
	SET_SIZE(xnor_instr)

	ENTRY(xnorcc_instr)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
 	xnorcc	%o0, %o1, %o1
	rd	%ccr, %o5
	stx	%o1, [%o2]
        retl
	stb	%o5, [%o3]
	SET_SIZE(xnorcc_instr)

	ENTRY(sll_instr)
	ldx	[%o0], %o0
 	sllx	%o0, %o1, %o0
        retl
	stx	%o0, [%o2]
	SET_SIZE(sll_instr)

	ENTRY(srl_instr)
        retl
 	srl	%o0, %o1, %o0
	SET_SIZE(srl_instr)

	ENTRY(srlx_instr)
	ldx	[%o0], %o0
 	srlx	%o0, %o1, %o0
        retl
	stx	%o0, [%o2]
	SET_SIZE(srlx_instr)


	
	ENTRY(sra_instr)
        retl
 	sra	%o0, %o1, %o0
	SET_SIZE(sra_instr)

	ENTRY(srax_instr)
	ldx	[%o0], %o0
 	srax	%o0, %o1, %o0
        retl
	stx	%o0, [%o2]
	SET_SIZE(srax_instr)

	ENTRY(mulx_instr)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
 	mulx	%o0, %o1, %o0
        retl
	stx	%o0, [%o2]
	SET_SIZE(mulx_instr)

	ENTRY(udivx_instr)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
 	udivx	%o0, %o1, %o0
        retl
	stx	%o0, [%o2]
	SET_SIZE(udivx_instr)

	ENTRY(sdivx_instr)
	ldx	[%o0], %o0
	ldx	[%o1], %o1
 	sdivx	%o0, %o1, %o0
        retl
	stx	%o0, [%o2]
	SET_SIZE(sdivx_instr)

	ENTRY(movcc_instr)
	ldx	[%o2], %o2 
	wr	%o1, %ccr
	mov	%o7, %o5
	jmpl	%o0, %o7
	nop
	mov	%o5, %o7
	brz,a	%o0, end_movcc
	st	%o0, [%o4]
	stx	%o2, [%o3]
end_movcc:
	retl
	nop
	SET_SIZE(movcc_instr)


	ENTRY(movfcc_instr)
	SETX(tmp_src,%o5,%g1,%g4)

	stx	%fsr, [%o5]
	ldx	[%o1], %fsr
	ldx	[%o2], %o2 
	mov	%o7, %o5
	jmpl	%o0, %o7
	nop
	mov	%o5, %o7
	brz,a	%o0, end_movfcc
	st	%o0, [%o4]
	stx	%o2, [%o3]
end_movfcc:
	SETX(tmp_src,%o5,%g1,%g4)
        retl
	ldx	[%o5], %fsr
	SET_SIZE(movfcc_instr)

	ENTRY(movr_instr)
	ldx	[%o1], %o1
	ldx	[%o2], %o2 
	mov	%o7, %o5
	jmpl	%o0, %o7
	nop
	mov	%o5, %o7
	brz,a	%o0, end_movr
	st	%o0, [%o4]
	stx	%o2, [%o3]
end_movr:
        retl
	nop
	SET_SIZE(movr_instr)

	ENTRY(fpop_ss2_sd)
	SETX(tmp_src,%o5,%g1,%g4)
	st	%f2, [%o5]
	st	%f4, [%o5 + 0x8]
	stx	%fsr, [%o5 + 0x10]

	ld	[%o2], %f2
	ld	[%o3], %f4
	ldx	[%o1], %fsr

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	stx	%fsr, [%o1]
	mov	%o5, %o7  ! Restore %o7
	st	%f4, [%o3] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ld	[%o5], %f2
	ld	[%o5 + 0x8], %f4
        retl
	ldx	[%o5 + 0x10], %fsr
	SET_SIZE(fpop_ss2_sd)

	ENTRY(fpop_ss2_dd)
	SETX(tmp_src,%o5,%g1,%g4)
	st	%f2, [%o5]
	std	%f4, [%o5 + 0x8]
	stx	%fsr, [%o5 + 0x10]

	ld	[%o2], %f2
	ldd	[%o3], %f4
	ldx	[%o1], %fsr

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	stx	%fsr, [%o1]
	mov	%o5, %o7  ! Restore %o7
	std	%f4, [%o3] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ld	[%o5], %f2
	ldd	[%o5 + 0x8], %f4
        retl
	ldx	[%o5 + 0x10], %fsr
	SET_SIZE(fpop_ss2_dd)

	ENTRY(fpop_ds2_sd)
	SETX(tmp_src,%o5,%g1,%g4)
	std	%f2, [%o5]
	st	%f4, [%o5 + 0x8]
	stx	%fsr, [%o5 + 0x10]

	ldd	[%o2], %f2
	ld	[%o3], %f4
	ldx	[%o1], %fsr

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	stx	%fsr, [%o1]
	mov	%o5, %o7  ! Restore %o7
	st	%f4, [%o3] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ldd	[%o5], %f2
	ld	[%o5 + 0x8], %f4
        retl
	ldx	[%o5 + 0x10], %fsr
	SET_SIZE(fpop_ds2_sd)

	ENTRY(fpop_ds2_dd)
	SETX(tmp_src,%o5,%g1,%g4)
	std	%f2, [%o5]
	std	%f4, [%o5 + 0x8]
	stx	%fsr, [%o5 + 0x10]

	ldd	[%o2], %f2
	ldd	[%o3], %f4
	ldx	[%o1], %fsr

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	stx	%fsr, [%o1]
	mov	%o5, %o7  ! Restore %o7
	std	%f4, [%o3] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ldd	[%o5], %f2
	ldd	[%o5 + 0x8], %f4
        retl
	ldx	[%o5 + 0x10], %fsr
	SET_SIZE(fpop_ds2_dd)

	ENTRY(fpop_ss1_ss2_sd)
	SETX(tmp_src,%o5,%g1,%g4)
	st	%f0, [%o5]
	st	%f2, [%o5 + 0x8]
	st	%f4, [%o5 + 0x10]
	stx	%fsr, [%o5 + 0x18]

	ld	[%o2], %f0
	ld	[%o3], %f2
	ld	[%o4], %f4
	ldx	[%o1], %fsr

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	stx	%fsr, [%o1]
	mov	%o5, %o7  ! Restore %o7
	st	%f4, [%o4] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ld	[%o5], %f0
	ld	[%o5 + 0x8], %f2
	ld	[%o5 + 0x10], %f4
        retl
	ldx	[%o5 + 0x18], %fsr
	SET_SIZE(fpop_ss1_ss2_sd)

	ENTRY(fpop_ss1_ss2_dd)
	SETX(tmp_src,%o5,%g1,%g4)
	st	%f0, [%o5]
	st	%f2, [%o5 + 0x8]
	std	%f4, [%o5 + 0x10]
	stx	%fsr, [%o5 + 0x18]

	ld	[%o2], %f0
	ld	[%o3], %f2
	ldd	[%o4], %f4
	ldx	[%o1], %fsr

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop
	stx	%fsr, [%o1]
	mov	%o5, %o7  ! Restore %o7
	std	%f4, [%o4] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ld	[%o5], %f0
	ld	[%o5 + 0x8], %f2
	ldd	[%o5 + 0x10], %f4
        retl
	ldx	[%o5 + 0x18], %fsr
	SET_SIZE(fpop_ss1_ss2_dd)

	ENTRY(fpop_ds1_ds2_sd)
	SETX(tmp_src,%o5,%g1,%g4)
	std	%f0, [%o5]
	std	%f2, [%o5 + 0x8]
	st	%f4, [%o5 + 0x10]
	stx	%fsr, [%o5 + 0x18]

	ldd	[%o2], %f0
	ldd	[%o3], %f2
	ld	[%o4], %f4
	ldx	[%o1], %fsr

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	stx	%fsr, [%o1]
	mov	%o5, %o7  ! Restore %o7
	st	%f4, [%o4] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ldd	[%o5], %f0
	ldd	[%o5 + 0x8], %f2
	ld	[%o5 + 0x10], %f4
        retl
	ldx	[%o5 + 0x18], %fsr
	SET_SIZE(fpop_ds1_ds2_sd)

	ENTRY(fpop_ds1_ds2_dd)
	SETX(tmp_src,%o5,%g1,%g4)
	std	%f0, [%o5]
	std	%f2, [%o5 + 0x8]
	std	%f4, [%o5 + 0x10]
	stx	%fsr, [%o5 + 0x18]

	ldd	[%o2], %f0
	ldd	[%o3], %f2
	ldd	[%o4], %f4
	ldx	[%o1], %fsr

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	stx	%fsr, [%o1]
	mov	%o5, %o7  ! Restore %o7
	std	%f4, [%o4] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ldd	[%o5], %f0
	ldd	[%o5 + 0x8], %f2
	ldd	[%o5 + 0x10], %f4
        retl
	ldx	[%o5 + 0x18], %fsr
	SET_SIZE(fpop_ds1_ds2_dd)

	ENTRY(fpop_ds1_ds2)
	SETX(tmp_src,%o5,%g1,%g4)
	std	%f0, [%o5]
	std	%f2, [%o5 + 0x8]
	stx	%fsr, [%o5 + 0x10]
	
	ldd	[%o3], %f2
	ldd	[%o2], %f0
	ldx	[%o1], %fsr
	
	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop
	
	mov	%o5, %o7  ! Restore %o7
	stx	%fsr, [%o1]

	SETX(tmp_src,%o5,%g1,%g4)
	ldd	[%o5], %f0
	ldd	[%o5 + 0x8], %f2
	ldx	[%o5 + 0x10], %fsr
        retl
	nop
	SET_SIZE(fpop_ds1_ds2)

	ENTRY(fpop_ss1_ss2)
	SETX(tmp_src,%o5,%g1,%g4)
	st	%f0, [%o5]
	st	%f2, [%o5 + 0x8]
	stx	%fsr,[%o5 + 0x10]

	ld	[%o2], %f0
	ld	[%o3], %f2
	ldx	[%o1], %fsr
	
	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	mov	%o5, %o7  ! Restore %o7
	stx	%fsr, [%o1]
	SETX(tmp_src,%o5,%g1,%g4)
	ld	[%o5], %f0
	ld	[%o5 + 0x8], %f2
	ldx	[%o5 + 0x10], %fsr
        retl
	nop
	SET_SIZE(fpop_ss1_ss2)

	ENTRY(fpop_ss2_sd_ic)
	SETX(tmp_src,%o5,%g1,%g4)
	st	%f2, [%o5]
	st	%f4, [%o5 + 0x8]
	stx	%fsr, [%o5 + 0x10]

	ld	[%o3], %f2
	ld	[%o4], %f4
	ldx	[%o1], %fsr
	wr	%o2, %ccr

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	mov	%o5, %o7  ! Restore %o7
	st	%f4, [%o4] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ld	[%o5], %f2
	ld	[%o5 + 0x8], %f4
	retl
	ldx	[%o5 + 0x10], %fsr
	SET_SIZE(fpop_ss2_sd_ic)

	ENTRY(fpop_ds2_dd_ic)
	SETX(tmp_src,%o5,%g1,%g4)
	std	%f2, [%o5]
	std	%f4, [%o5 + 0x8]
	stx	%fsr, [%o5 + 0x10]

	ldd	[%o3], %f2
	ldd	[%o4], %f4
	ldx	[%o1], %fsr
	wr	%o2, %ccr

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	mov	%o5, %o7  ! Restore %o7
	std	%f4, [%o4] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ldd	[%o5], %f2
	ldd	[%o5 + 0x8], %f4
	retl
	ldx	[%o5 + 0x10], %fsr
	SET_SIZE(fpop_ds2_dd_ic)

	ENTRY(fpop_ss2_sd_ir)
	SETX(tmp_src,%o5,%g1,%g4)
	st	%f2, [%o5]
	st	%f4, [%o5 + 0x8]

	ld	[%o3], %f2
	ld	[%o4], %f4

	mov	%o7, %o5  ! Save %o7
	sllx	%o1, 0x20, %o1
	or	%o1, %o2, %o1
	jmpl	%o0, %o7
	nop

	mov	%o5, %o7  ! Restore %o7
	st	%f4, [%o4] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ld	[%o5], %f2
        retl
	ld	[%o5 + 0x8], %f4
	SET_SIZE(fpop_ss2_sd_ir)

	ENTRY(fpop_ds2_dd_ir)
	SETX(tmp_src,%o5,%g1,%g4)
	std	%f2, [%o5]
	std	%f4, [%o5 + 0x8]

	ldd	[%o3], %f2
	ldd	[%o4], %f4

	mov	%o7, %o5  ! Save %o7
	sllx	%o1, 0x20, %o1
	or	%o1, %o2, %o1
	jmpl	%o0, %o7
	nop

	mov	%o5, %o7  ! Restore %o7
	std	%f4, [%o4] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ldd	[%o5], %f2
        retl
	ldd	[%o5 + 0x8], %f4
	SET_SIZE(fpop_ds2_dd_ir)

	ENTRY(gop_sd)
	SETX(tmp_src,%o5,%g1,%g4)
	st	%f4, [%o5]

	ld	[%o1], %f4

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	mov	%o5, %o7  ! Restore %o7
	st	%f4, [%o1] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
        retl
	ld	[%o5], %f4
	SET_SIZE(gop_sd)

	ENTRY(gop_dd)
	SETX(tmp_src,%o5,%g1,%g4)
	std	%f4, [%o5]

	ldd	[%o1], %f4

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	mov	%o5, %o7  ! Restore %o7
	std	%f4, [%o1] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
        retl
	ldd	[%o5], %f4
	SET_SIZE(gop_dd)

	ENTRY(gop_ss_sd)
	SETX(tmp_src,%o5,%g1,%g4)
	st	%f2, [%o5]
	st	%f4, [%o5 + 0x8]

	ld	[%o1], %f2
	ld	[%o2], %f4

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	mov	%o5, %o7  ! Restore %o7
	st	%f4, [%o2] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ld	[%o5], %f2
        retl
	ld	[%o5 + 0x8], %f4
	SET_SIZE(gop_ss_sd)

	ENTRY(gop_ds_dd)
	SETX(tmp_src,%o5,%g1,%g4)
	std	%f2, [%o5]
	std	%f4, [%o5 + 0x8]

	ldd	[%o1], %f2
	ldd	[%o2], %f4

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	mov	%o5, %o7  ! Restore %o7
	std	%f4, [%o2] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ldd	[%o5], %f2
        retl
	ldd	[%o5 + 0x8], %f4
	SET_SIZE(gop_ds_dd)

	ENTRY(gop_ss2_dd)
	SETX(tmp_src,%o5,%g1,%g4)
	st	%f2, [%o5]
	std	%f4, [%o5 + 0x8]

	ld	[%o1], %f2
	ldd	[%o2], %f4

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	mov	%o5, %o7  ! Restore %o7
	std	%f4, [%o2] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ld	[%o5], %f2
        retl
	ldd	[%o5 + 0x8], %f4
	SET_SIZE(gop_ss2_dd)

	ENTRY(gop_ds2_sd_gr)
	SETX(tmp_src,%o5,%g1,%g4)
	std	%f2, [%o5]
	st	%f4, [%o5 + 0x8]
	rd	%gsr, %o4

	ldd	[%o2], %f2
	!ld	[%o3], %f4
	wr	%o1, 0x0, %asr19

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	mov	%o5, %o7  ! Restore %o7
	st	%f4, [%o3] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ldd	[%o5], %f2
	ld	[%o5 + 0x8], %f4
        retl
	wr	%o4, 0x0, %asr19
	SET_SIZE(gop_ds2_sd_gr)

	ENTRY(gop_ss1_ds2_dd)
	SETX(tmp_src,%o5,%g1,%g4)
	st	%f0, [%o5]
	std	%f2, [%o5 + 0x8]
	std	%f4, [%o5 + 0x10]

	ld	[%o1], %f0
	ldd	[%o2], %f2
	ldd	[%o3], %f4

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop
	mov	%o5, %o7  ! Restore %o7
	std	%f4, [%o3] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ld	[%o5], %f0
	ldd	[%o5 + 0x8], %f2
        retl
	ldd	[%o5 + 0x10], %f4
	SET_SIZE(gop_ss1_ds2_dd)

	ENTRY(gop_ds1_ds2_dd)
	SETX(tmp_src,%o5,%g1,%g4)
	std	%f0, [%o5]
	std	%f2, [%o5 + 0x8]
	std	%f4, [%o5 + 0x10]

	ldd	[%o1], %f0
	ldd	[%o2], %f2
	ldd	[%o3], %f4

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop
	mov	%o5, %o7  ! Restore %o7
	std	%f4, [%o3] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ldd	[%o5], %f0
	ldd	[%o5 + 0x8], %f2
        retl
	ldd	[%o5 + 0x10], %f4
	SET_SIZE(gop_ds1_ds2_dd)

	ENTRY(gop_ds1_ds2_id)
	SETX(tmp_src,%o5,%g1,%g4)
	std	%f0, [%o5]
	std	%f2, [%o5 + 0x8]

	ldd	[%o1], %f0
	ldd	[%o2], %f2

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop
	mov	%o5, %o7  ! Restore %o7
	stx	%o4, [%o3] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ldd	[%o5], %f0
        retl
	ldd	[%o5 + 0x8], %f2
	SET_SIZE(gop_ds1_ds2_id)

	ENTRY(gop_ss1_ss2_dd)
	SETX(tmp_src,%o5,%g1,%g4)
	st	%f0, [%o5]
	st	%f2, [%o5 + 0x8]
	std	%f4, [%o5 + 0x10]

	ld	[%o1], %f0
	ld	[%o2], %f2
	ldd	[%o3], %f4

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop
	mov	%o5, %o7  ! Restore %o7
	std	%f4, [%o3] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ld	[%o5], %f0
	ld	[%o5 + 0x8], %f2
        retl
	ldd	[%o5 + 0x10], %f4
	SET_SIZE(gop_ss1_ss2_dd)

	ENTRY(gop_ss1_ss2_sd)
	SETX(tmp_src,%o5,%g1,%g4)
	st	%f0, [%o5]
	st	%f2, [%o5 + 0x8]
	st	%f4, [%o5 + 0x10]

	ld	[%o1], %f0
	ld	[%o2], %f2
	ld	[%o3], %f4

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop
	mov	%o5, %o7  ! Restore %o7
	st	%f4, [%o3] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ld	[%o5], %f0
	ld	[%o5 + 0x8], %f2
        retl
	ld	[%o5 + 0x10], %f4
	SET_SIZE(gop_ss1_ss2_sd)

	ENTRY(gop_ds1_ds2_dd_gr)
	SETX(tmp_src,%o5,%g1,%g4)
	std	%f0, [%o5]
	std	%f2, [%o5 + 0x8]
	std	%f4, [%o5 + 0x10]

	ldd	[%o2], %f0
	ldd	[%o3], %f2
	ldd	[%o4], %f4
	rd	%gsr, %o2
	wr	%o1, 0x0, %asr19

	mov	%o7, %o5  ! Save %o7
	jmpl	%o0, %o7
	nop

	mov	%o5, %o7  ! Restore %o7
	std	%f4, [%o4] ! Store value to dst reg
	SETX(tmp_src,%o5,%g1,%g4)
	ldd	[%o5], %f0
	ldd	[%o5 + 0x8], %f2
	ldd	[%o5 + 0x10], %f4
        retl
	wr	%o2, 0x0, %asr19
	SET_SIZE(gop_ds1_ds2_dd_gr)

	ENTRY(gop_array_instr)
	ldx	[%o1], %o1
	ldx	[%o2], %o2

	mov	%o7, %o4  ! Save %o7
	jmpl	%o0, %o7
	nop

	mov	%o4, %o7  ! Restore %o7
        retl
	stx	%o5, [%o3] ! Store value to dst reg
	SET_SIZE(gop_array_instr)

	ENTRY(gop_align_instr)
	ld	[%o1], %g5
	ldx	[%o2], %o2
	ldx	[%o3], %o3
	rd	%gsr, %g4
	wr	%g5, 0, %asr19

	mov	%o7, %g5  ! Save %o7
	jmpl	%o0, %o7
	nop

	mov	%g5, %o7  ! Restore %o7
	stx	%o5, [%o4] ! Store value to dst reg
	rd	%gsr, %g5
	wr	%g4, 0, %asr19
        retl
	st	%g5, [%o1]
	SET_SIZE(gop_align_instr)

	ENTRY(gop_edges_instr)
	ldx	[%o2], %o2
	ldx	[%o3], %o3
	ldub	[%o1], %o5
	wr	%o5, %ccr

	mov	%o7, %g4  ! Save %o7
	jmpl	%o0, %o7
	nop

	mov	%g4, %o7  ! Restore %o7
	stx	%o5, [%o4] ! Store value to dst reg
	rd	%ccr, %o5
	retl
	stb	%o5, [%o1]
	SET_SIZE(gop_edges_instr)

        .seg    "data"
	.global	tmp_src
	.align	8
tmp_src:
	.word	0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
